package net.pingfang.devicelock.Config;

import lombok.extern.slf4j.Slf4j;
import net.pingfang.devicelock.AsyncHandler;
import net.pingfang.devicelock.Decoder.ByteArray7ESerializer;
import net.pingfang.devicelock.common.ParamCommon;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.integration.annotation.MessageEndpoint;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.ExecutorChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.ip.tcp.TcpInboundGateway;
import org.springframework.integration.ip.tcp.TcpSendingMessageHandler;
import org.springframework.integration.ip.tcp.connection.AbstractClientConnectionFactory;
import org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory;
import org.springframework.messaging.MessageChannel;

import java.util.ArrayList;


/**
 * 当前类使用integration.ip框架监听TCP端口报文并转译
 * 第一步创建TcpNetServerConnectionFactory 连接工厂
 * 第二步定义 消息通道
 * 第三步 定义 TCP 入站通道适配器
 * 系统与电子锁直接进行Tcp通信
 * 电子锁的4G信号不稳定，所以需要阅读器
 */
@Configuration
@Slf4j
@MessageEndpoint
@EnableIntegration
public class TcpServerConfig  {

    @Value("${device.lock.socket.port}")
    private int port;

    @Value("${device.lock.send.host}")
    private String host;

    private final TaskExecutor taskExecutor;

    private final AsyncHandler asyncHandler;  // 异步处理器

    @Autowired  // 当有多个同名Bean时需显式指定
    public TcpServerConfig(@Qualifier("tcpTaskExecutor") TaskExecutor tcpTaskExecutor,
                           AsyncHandler asyncHandler) {
        this.taskExecutor = tcpTaskExecutor;
        this.asyncHandler = asyncHandler;
    }


    // 定义 TCP 服务端连接工厂 使用换行符接收报文，若不存在换行符则接收不到信息
    @Bean
    public TcpNetServerConnectionFactory tcpServerFactory() {
        return ParamCommon.toTcpServerFactory(port,new ByteArray7ESerializer(),taskExecutor);
    }

    /*
     * 接收阅读器返回响应报文 指定锁名称 操作口令
     * 作为Client客户端进行发送报文
     * */


    // 定义消息通道
    @Bean(name="tcpInputChannel")
    public MessageChannel tcpInputChannel() {
        ExecutorChannel channel = new ExecutorChannel(taskExecutor);
        // 明确指定泛型类型
        channel.setInterceptors(new ArrayList<>());
        return channel;
    }

    @ServiceActivator(inputChannel = "tcpInputChannel")
    public void handleMessage(byte[] payload) {
        asyncHandler.process(payload);  // 触发异步处理
    }



    // 定义 TCP 入站通道适配器
    @Bean
    public TcpInboundGateway tcpInboundGateway() {
        TcpInboundGateway gateway = new TcpInboundGateway();
        gateway.setConnectionFactory(tcpServerFactory());
        gateway.setRequestChannel(tcpInputChannel());
        return gateway;
    }

    @Bean
    public AbstractClientConnectionFactory clientConnectionFactory() {
        return ParamCommon.clientConnectionFactory(port,host,taskExecutor);
    }


    @Bean
    public MessageChannel outboundChannel() {
        ExecutorChannel channel = new ExecutorChannel(taskExecutor);
        // 明确指定泛型类型
        channel.setInterceptors(new ArrayList<>());
        return channel;
    }


    @Bean
    @ServiceActivator(inputChannel = "outboundChannel")
    public TcpSendingMessageHandler tcpOutbound(
            @Qualifier("clientConnectionFactory") AbstractClientConnectionFactory connectionFactory) {
        TcpSendingMessageHandler handler = new TcpSendingMessageHandler();
        handler.setConnectionFactory(connectionFactory);
        return handler;
    }

//    @Bean
//    @ServiceActivator(inputChannel = "out_hhd_boundChannel")
//    public TcpSendingMessageHandler HHD_tcpOutbound(
//            @Qualifier("HHD_clientConnectionFactory") AbstractClientConnectionFactory connectionFactory) {
//        TcpSendingMessageHandler handler = new TcpSendingMessageHandler();
//        handler.setConnectionFactory(connectionFactory);
//        return handler;
//    }







}
